package com.example.canal.kafka;

import com.alibaba.fastjson.JSONObject;

import com.example.canal.common.constant.MysqlDBConstant;
import com.example.canal.common.bean.CanalBean;
import com.example.canal.entity.TbCommodityInfo;
import com.example.canal.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.support.Acknowledgment;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author LiYuhang
 * @version 0.1
 * @application kafka 监听 canal 发送过来的消息 同步至redis
 * @Date 2021/8/8 16:29
 */
@Component
@Slf4j
public class CanalRedisConsumer {


    final RedisUtil redisUtil;

    @Autowired
    public CanalRedisConsumer(RedisUtil redisUtil) {
        this.redisUtil = redisUtil;
    }


    /**
     * 监听的队列名称为：canaltopic
     *
     * @param consumer
     * @param ack
     */
    @KafkaListener(topics = "canaltopic", groupId = "topic.canal")
    public void receive(ConsumerRecord<?, ?> consumer,Acknowledgment ack) {
        String value = (String) consumer.value();
        log.info("topic名称:{},key:{},分区位置:{},下标:{},value:{}",consumer.topic(),consumer.key(),consumer.partition(),consumer.offset(),value);
        //转换为javaBean
        CanalBean canalBean = JSONObject.parseObject(value,CanalBean.class);
        processData(canalBean);
        ack.acknowledge();
    }

    /**
     * 讲数据 推送至redis
     *
     * @param canalBean
     */
    private void processData(CanalBean canalBean) {
        //获取是否是DDL语句
        boolean isDdl = canalBean.isDdl();
        if (isDdl) {
            return;
        }
        //获取类型
        String type = canalBean.getType();
        //不是DDL语句
        if (!isDdl) {
            Map<String, TbCommodityInfo> collect = canalBean
                    .getData()
                    .stream()
                    .map(v -> JSONObject.parseObject(v,TbCommodityInfo.class))
                    .collect(Collectors.toMap(TbCommodityInfo::getId,Function.identity()));
            if (MysqlDBConstant.TYPE_INSERT.equals(type) || MysqlDBConstant.TYPE_UPDATE.equals(type)) {
                redisUtil.multiSet(collect);
            } else if (MysqlDBConstant.TYPE_DELETE.equals(type)) {
                //删除语句 从redis中删除
                redisUtil.del(collect.keySet());
            }
        }

    }

}
